////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2000 Andrei Alexandrescu
// Copyright (c) 2000 Petru Marginean
// Copyright (c) 2005 Joshua Lehrer
// Code covered by the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_SCOPEGUARD_INC_
#define LOKI_SCOPEGUARD_INC_

// $Id$

#include <exception> // needed for calls to uncaught_exception.

#include "Concatenate.h"
#include "RefToValue.h"

/// \defgroup ExceptionGroup Exception-safe code

namespace Loki {

////////////////////////////////////////////////////////////////
///
/// \class ScopeGuardImplBase
/// \ingroup ExceptionGroup
///
/// Base class used by all ScopeGuard implementations.  All commonly used
/// functions are in this class (e.g. - Dismiss and SafeExecute).
///
/// See Andrei's and Petru Marginean's CUJ article
/// http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/alexandr.htm
///
/// Changes to the original code by Joshua Lehrer:
/// http://www.lehrerfamily.com/scopeguard.html
////////////////////////////////////////////////////////////////

class ScopeGuardImplBase {

public:
  enum ExceptionPolicy {
    AlwaysExecute = 0,
    CallIfNoException = 1,
    CallIfException = 2
  };

  ScopeGuardImplBase() throw()
      : dismissed_(false), exceptionPolicy_(AlwaysExecute) {}

  void Dismiss() const throw() { dismissed_ = true; }

  void SetExceptionPolicy(ExceptionPolicy policy) const throw() {
    exceptionPolicy_ = policy;
  }

private:
  /// Copy-assignment operator is not implemented and private.
  ScopeGuardImplBase &operator=(const ScopeGuardImplBase &);

protected:
  ~ScopeGuardImplBase() {}

  /// Copy-constructor takes over responsibility from other ScopeGuard.
  ScopeGuardImplBase(const ScopeGuardImplBase &other) throw()
      : dismissed_(other.dismissed_), exceptionPolicy_(other.exceptionPolicy_) {
    other.Dismiss();
  }

  template <typename J> static void SafeExecute(J &j) throw() {
    if (AlwaysExecute != j.exceptionPolicy_) {
      const bool anyThrown = ::std::uncaught_exception();
      if (anyThrown) {
        if (CallIfNoException == j.exceptionPolicy_)
          j.Dismiss();
      } else if (CallIfException == j.exceptionPolicy_) {
        j.Dismiss();
      }
    }
    if (!j.dismissed_) {
      try {
        j.Execute();
      } catch (...) {
      }
    }
  }

  mutable bool dismissed_;
  mutable ExceptionPolicy exceptionPolicy_;
};

////////////////////////////////////////////////////////////////
///
/// \typedef typedef const ScopeGuardImplBase& ScopeGuard
/// \ingroup ExceptionGroup
///
////////////////////////////////////////////////////////////////

typedef const ScopeGuardImplBase &ScopeGuard;

////////////////////////////////////////////////////////////////
///
/// \class ScopeGuardImpl0
/// \ingroup ExceptionGroup
///
/// Implementation class for a standalone function or class static function
/// with no parameters.  ScopeGuard ignores any value returned from the
/// call within the Execute function.
///
/// This class has a single standalone helper function, MakeGuard which
/// creates and returns a ScopeGuard.
///
////////////////////////////////////////////////////////////////

template <typename F> class ScopeGuardImpl0 : public ScopeGuardImplBase {
public:
  static ScopeGuardImpl0<F> MakeGuard(F fun) { return ScopeGuardImpl0<F>(fun); }

  ~ScopeGuardImpl0() throw() { SafeExecute(*this); }

  void Execute() { fun_(); }

protected:
  ScopeGuardImpl0(F fun) : fun_(fun) {}

  F fun_;
};

template <typename F> inline ScopeGuardImpl0<F> MakeGuard(F fun) {
  return ScopeGuardImpl0<F>::MakeGuard(fun);
}

////////////////////////////////////////////////////////////////
///
/// \class ScopeGuardImpl1
/// \ingroup ExceptionGroup
///
/// Implementation class for a standalone function or class static function
/// with one parameter.  Each parameter is copied by value - use
/// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
/// any value returned from the call within the Execute function.
///
/// This class has a single standalone helper function, MakeGuard which
/// creates and returns a ScopeGuard.
///
////////////////////////////////////////////////////////////////

template <typename F, typename P1>
class ScopeGuardImpl1 : public ScopeGuardImplBase {
public:
  static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1) {
    return ScopeGuardImpl1<F, P1>(fun, p1);
  }

  ~ScopeGuardImpl1() throw() { SafeExecute(*this); }

  void Execute() { fun_(p1_); }

protected:
  ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1) {}

  F fun_;
  const P1 p1_;
};

template <typename F, typename P1>
inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1) {
  return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
}

////////////////////////////////////////////////////////////////
///
/// \class ScopeGuardImpl2
/// \ingroup ExceptionGroup
///
/// Implementation class for a standalone function or class static function
/// with two parameters.  Each parameter is copied by value - use
/// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
/// any value returned from the call within the Execute function.
///
/// This class has a single standalone helper function, MakeGuard which
/// creates and returns a ScopeGuard.
///
////////////////////////////////////////////////////////////////

template <typename F, typename P1, typename P2>
class ScopeGuardImpl2 : public ScopeGuardImplBase {
public:
  static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2) {
    return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
  }

  ~ScopeGuardImpl2() throw() { SafeExecute(*this); }

  void Execute() { fun_(p1_, p2_); }

protected:
  ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2) {}

  F fun_;
  const P1 p1_;
  const P2 p2_;
};

template <typename F, typename P1, typename P2>
inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2) {
  return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
}

////////////////////////////////////////////////////////////////
///
/// \class ScopeGuardImpl3
/// \ingroup ExceptionGroup
///
/// Implementation class for a standalone function or class static function
/// with three parameters.  Each parameter is copied by value - use
/// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
/// any value returned from the call within the Execute function.
///
/// This class has a single standalone helper function, MakeGuard which
/// creates and returns a ScopeGuard.
///
////////////////////////////////////////////////////////////////

template <typename F, typename P1, typename P2, typename P3>
class ScopeGuardImpl3 : public ScopeGuardImplBase {
public:
  static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3) {
    return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
  }

  ~ScopeGuardImpl3() throw() { SafeExecute(*this); }

  void Execute() { fun_(p1_, p2_, p3_); }

protected:
  ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3)
      : fun_(fun), p1_(p1), p2_(p2), p3_(p3) {}

  F fun_;
  const P1 p1_;
  const P2 p2_;
  const P3 p3_;
};

template <typename F, typename P1, typename P2, typename P3>
inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3) {
  return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3);
}

////////////////////////////////////////////////////////////////
///
/// \class ScopeGuardImpl4
/// \ingroup ExceptionGroup
///
/// Implementation class for a standalone function or class static function
/// with four parameters.  Each parameter is copied by value - use
/// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
/// any value returned from the call within the Execute function.
///
/// This class has a single standalone helper function, MakeGuard which
/// creates and returns a ScopeGuard.
///
////////////////////////////////////////////////////////////////

template <typename F, typename P1, typename P2, typename P3, typename P4>
class ScopeGuardImpl4 : public ScopeGuardImplBase {
public:
  static ScopeGuardImpl4<F, P1, P2, P3, P4> MakeGuard(F fun, P1 p1, P2 p2,
                                                      P3 p3, P4 p4) {
    return ScopeGuardImpl4<F, P1, P2, P3, P4>(fun, p1, p2, p3, p4);
  }

  ~ScopeGuardImpl4() throw() { SafeExecute(*this); }

  void Execute() { fun_(p1_, p2_, p3_, p4_); }

protected:
  ScopeGuardImpl4(F fun, P1 p1, P2 p2, P3 p3, P4 p4)
      : fun_(fun), p1_(p1), p2_(p2), p3_(p3), p4_(p4) {}

  F fun_;
  const P1 p1_;
  const P2 p2_;
  const P3 p3_;
  const P4 p4_;
};

template <typename F, typename P1, typename P2, typename P3, typename P4>
inline ScopeGuardImpl4<F, P1, P2, P3, P4> MakeGuard(F fun, P1 p1, P2 p2, P3 p3,
                                                    P4 p4) {
  return ScopeGuardImpl4<F, P1, P2, P3, P4>::MakeGuard(fun, p1, p2, p3, p4);
}

////////////////////////////////////////////////////////////////
///
/// \class ScopeGuardImpl5
/// \ingroup ExceptionGroup
///
/// Implementation class for a standalone function or class static function
/// with five parameters.  Each parameter is copied by value - use
/// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
/// any value returned from the call within the Execute function.
///
/// This class has a single standalone helper function, MakeGuard which
/// creates and returns a ScopeGuard.
///
////////////////////////////////////////////////////////////////

template <typename F, typename P1, typename P2, typename P3, typename P4,
          typename P5>
class ScopeGuardImpl5 : public ScopeGuardImplBase {
public:
  static ScopeGuardImpl5<F, P1, P2, P3, P4, P5> MakeGuard(F fun, P1 p1, P2 p2,
                                                          P3 p3, P4 p4, P5 p5) {
    return ScopeGuardImpl5<F, P1, P2, P3, P4, P5>(fun, p1, p2, p3, p4, p5);
  }

  ~ScopeGuardImpl5() throw() { SafeExecute(*this); }

  void Execute() { fun_(p1_, p2_, p3_, p4_, p5_); }

protected:
  ScopeGuardImpl5(F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
      : fun_(fun), p1_(p1), p2_(p2), p3_(p3), p4_(p4), p5_(p5) {}

  F fun_;
  const P1 p1_;
  const P2 p2_;
  const P3 p3_;
  const P4 p4_;
  const P5 p5_;
};

template <typename F, typename P1, typename P2, typename P3, typename P4,
          typename P5>
inline ScopeGuardImpl5<F, P1, P2, P3, P4, P5> MakeGuard(F fun, P1 p1, P2 p2,
                                                        P3 p3, P4 p4, P5 p5) {
  return ScopeGuardImpl5<F, P1, P2, P3, P4, P5>::MakeGuard(fun, p1, p2, p3, p4,
                                                           p5);
}

////////////////////////////////////////////////////////////////
///
/// \class ObjScopeGuardImpl0
/// \ingroup ExceptionGroup
///
/// Implementation class for a class per-instance member function with no
/// parameters.  ScopeGuard ignores any value returned from the call within
/// the Execute function.
///
/// This class has 3 standalone helper functions which create a ScopeGuard.
/// One is MakeObjGuard, which is deprecated but provided for older code.
/// The other two are MakeGuard overloads, one which takes a pointer to an
/// object, and the other which takes a reference.
///
////////////////////////////////////////////////////////////////

template <class Obj, typename MemFun>
class ObjScopeGuardImpl0 : public ScopeGuardImplBase {
public:
  static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj &obj, MemFun memFun) {
    return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
  }

  ~ObjScopeGuardImpl0() throw() { SafeExecute(*this); }

  void Execute() { (obj_.*memFun_)(); }

protected:
  ObjScopeGuardImpl0(Obj &obj, MemFun memFun) : obj_(obj), memFun_(memFun) {}

  Obj &obj_;
  MemFun memFun_;
};

template <class Obj, typename MemFun>
inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj &obj, MemFun memFun) {
  return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(obj, memFun);
}

template <typename Ret, class Obj1, class Obj2>
inline ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()>
MakeGuard(Ret (Obj2::*memFun)(), Obj1 &obj) {
  return ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()>::MakeObjGuard(obj, memFun);
}

template <typename Ret, class Obj1, class Obj2>
inline ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()>
MakeGuard(Ret (Obj2::*memFun)(), Obj1 *obj) {
  return ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()>::MakeObjGuard(*obj, memFun);
}

////////////////////////////////////////////////////////////////
///
/// \class ObjScopeGuardImpl1
/// \ingroup ExceptionGroup
///
/// Implementation class for a class per-instance member function with one
/// parameter.  The parameter is copied by value - use ::Loki::ByRef if you
/// must use a reference instead.  ScopeGuard ignores any value returned
/// from the call within the Execute function.
///
/// This class has 3 standalone helper functions which create a ScopeGuard.
/// One is MakeObjGuard, which is deprecated but provided for older code.
/// The other two are MakeGuard overloads, one which takes a pointer to an
/// object, and the other which takes a reference.
///
////////////////////////////////////////////////////////////////

template <class Obj, typename MemFun, typename P1>
class ObjScopeGuardImpl1 : public ScopeGuardImplBase {
public:
  static ObjScopeGuardImpl1<Obj, MemFun, P1>
  MakeObjGuard(Obj &obj, MemFun memFun, P1 p1) {
    return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
  }

  ~ObjScopeGuardImpl1() throw() { SafeExecute(*this); }

  void Execute() { (obj_.*memFun_)(p1_); }

protected:
  ObjScopeGuardImpl1(Obj &obj, MemFun memFun, P1 p1)
      : obj_(obj), memFun_(memFun), p1_(p1) {}

  Obj &obj_;
  MemFun memFun_;
  const P1 p1_;
};

template <class Obj, typename MemFun, typename P1>
inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj &obj, MemFun memFun,
                                                        P1 p1) {
  return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(obj, memFun, p1);
}

template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
inline ObjScopeGuardImpl1<Obj1, Ret (Obj2::*)(P1a), P1b>
MakeGuard(Ret (Obj2::*memFun)(P1a), Obj1 &obj, P1b p1) {
  return ObjScopeGuardImpl1<Obj1, Ret (Obj2::*)(P1a), P1b>::MakeObjGuard(
      obj, memFun, p1);
}

template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
inline ObjScopeGuardImpl1<Obj1, Ret (Obj2::*)(P1a), P1b>
MakeGuard(Ret (Obj2::*memFun)(P1a), Obj1 *obj, P1b p1) {
  return ObjScopeGuardImpl1<Obj1, Ret (Obj2::*)(P1a), P1b>::MakeObjGuard(
      *obj, memFun, p1);
}

////////////////////////////////////////////////////////////////
///
/// \class ObjScopeGuardImpl2
/// \ingroup ExceptionGroup
///
/// Implementation class for a class per-instance member function with two
/// parameters.  Each parameter is copied by value - use ::Loki::ByRef if you
/// must use a reference instead.  ScopeGuard ignores any value returned
/// from the call within the Execute function.
///
/// This class has 3 standalone helper functions which create a ScopeGuard.
/// One is MakeObjGuard, which is deprecated but provided for older code.
/// The other two are MakeGuard overloads, one which takes a pointer to an
/// object, and the other which takes a reference.
///
////////////////////////////////////////////////////////////////

template <class Obj, typename MemFun, typename P1, typename P2>
class ObjScopeGuardImpl2 : public ScopeGuardImplBase {
public:
  static ObjScopeGuardImpl2<Obj, MemFun, P1, P2>
  MakeObjGuard(Obj &obj, MemFun memFun, P1 p1, P2 p2) {
    return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
  }

  ~ObjScopeGuardImpl2() throw() { SafeExecute(*this); }

  void Execute() { (obj_.*memFun_)(p1_, p2_); }

protected:
  ObjScopeGuardImpl2(Obj &obj, MemFun memFun, P1 p1, P2 p2)
      : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2) {}

  Obj &obj_;
  MemFun memFun_;
  const P1 p1_;
  const P2 p2_;
};

template <class Obj, typename MemFun, typename P1, typename P2>
inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2>
MakeObjGuard(Obj &obj, MemFun memFun, P1 p1, P2 p2) {
  return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(obj, memFun, p1,
                                                               p2);
}

template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b,
          typename P2a, typename P2b>
inline ObjScopeGuardImpl2<Obj1, Ret (Obj2::*)(P1a, P2a), P1b, P2b>
MakeGuard(Ret (Obj2::*memFun)(P1a, P2a), Obj1 &obj, P1b p1, P2b p2) {
  return ObjScopeGuardImpl2<Obj1, Ret (Obj2::*)(P1a, P2a), P1b,
                            P2b>::MakeObjGuard(obj, memFun, p1, p2);
}

template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b,
          typename P2a, typename P2b>
inline ObjScopeGuardImpl2<Obj1, Ret (Obj2::*)(P1a, P2a), P1b, P2b>
MakeGuard(Ret (Obj2::*memFun)(P1a, P2a), Obj1 *obj, P1b p1, P2b p2) {
  return ObjScopeGuardImpl2<Obj1, Ret (Obj2::*)(P1a, P2a), P1b,
                            P2b>::MakeObjGuard(*obj, memFun, p1, p2);
}

////////////////////////////////////////////////////////////////
///
/// \class ObjScopeGuardImpl3
/// \ingroup ExceptionGroup
///
/// Implementation class for a class per-instance member function with three
/// parameters.  Each parameter is copied by value - use ::Loki::ByRef if you
/// must use a reference instead.  ScopeGuard ignores any value returned
/// from the call within the Execute function.
///
/// This class has 3 standalone helper functions which create a ScopeGuard.
/// One is MakeObjGuard, which is deprecated but provided for older code.
/// The other two are MakeGuard overloads, one which takes a pointer to an
/// object, and the other which takes a reference.
///
////////////////////////////////////////////////////////////////

template <class Obj, typename MemFun, typename P1, typename P2, typename P3>
class ObjScopeGuardImpl3 : public ScopeGuardImplBase {
public:
  static ObjScopeGuardImpl3<Obj, MemFun, P1, P2, P3>
  MakeObjGuard(Obj &obj, MemFun memFun, P1 p1, P2 p2, P3 p3) {
    return ObjScopeGuardImpl3<Obj, MemFun, P1, P2, P3>(obj, memFun, p1, p2, p3);
  }

  ~ObjScopeGuardImpl3() throw() { SafeExecute(*this); }

  void Execute() { (obj_.*memFun_)(p1_, p2_, p3_); }

protected:
  ObjScopeGuardImpl3(Obj &obj, MemFun memFun, P1 p1, P2 p2, P3 p3)
      : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2), p3_(p3) {}

  Obj &obj_;
  MemFun memFun_;
  const P1 p1_;
  const P2 p2_;
  const P3 p3_;
};

template <class Obj, typename MemFun, typename P1, typename P2, typename P3>
inline ObjScopeGuardImpl3<Obj, MemFun, P1, P2, P3>
MakeObjGuard(Obj &obj, MemFun memFun, P1 p1, P2 p2, P3 p3) {
  return ObjScopeGuardImpl3<Obj, MemFun, P1, P2, P3>::MakeObjGuard(obj, memFun,
                                                                   p1, p2, p3);
}

template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b,
          typename P2a, typename P2b, typename P3a, typename P3b>
inline ObjScopeGuardImpl3<Obj1, Ret (Obj2::*)(P1a, P2a, P3a), P1b, P2b, P3b>
MakeGuard(Ret (Obj2::*memFun)(P1a, P2a, P3a), Obj1 &obj, P1b p1, P2b p2,
          P3b p3) {
  return ObjScopeGuardImpl3<Obj1, Ret (Obj2::*)(P1a, P2a, P3a), P1b, P2b,
                            P3b>::MakeObjGuard(obj, memFun, p1, p2, p3);
}

template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b,
          typename P2a, typename P2b, typename P3a, typename P3b>
inline ObjScopeGuardImpl3<Obj1, Ret (Obj2::*)(P1a, P2a, P3a), P1b, P2b, P3b>
MakeGuard(Ret (Obj2::*memFun)(P1a, P2a, P3a), Obj1 *obj, P1b p1, P2b p2,
          P3b p3) {
  return ObjScopeGuardImpl3<Obj1, Ret (Obj2::*)(P1a, P2a, P3a), P1b, P2b,
                            P3b>::MakeObjGuard(*obj, memFun, p1, p2, p3);
}

} // namespace Loki

#define LOKI_ANONYMOUS_VARIABLE(str) LOKI_CONCATENATE(str, __LINE__)

#define LOKI_ON_BLOCK_EXIT                                                     \
  ::Loki::ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = ::Loki::MakeGuard
#define LOKI_ON_BLOCK_EXIT_OBJ                                                 \
  ::Loki::ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = ::Loki::MakeObjGuard

#endif // end file guardian
